# 创建时间:2022/12/6 18:36
# 创建人:天霄
# 计划 :项目工具
# 文件 :tolog.py
# 基于 Python 3.8.2
# ========================================
# 日志方法
# ========================================
import logging
import time
from Common.Tools.get_config import GetConfig


def _init_log(name, time_level=1):
    """初始化logger，分为打印日志、运行日志、错误日志

    :param name: 日志名，同时也是文件前缀名
    :param time_level: 日志文件时间记录级别，默认1（1秒，2分，3时，4日，5月）
    :return: logger
    """
    if not GetConfig.OpenLog:
        class EmptyLogger:
            def debug(self, *args, **kwargs): ...
            def info(self, *args, **kwargs): ...
            def tip(self, *args, **kwargs): ...
            def warning(self, *args, **kwargs): ...
            def mark(self, *args, **kwargs): ...
            def error(self, *args, **kwargs): ...
            def exception(self, *args, **kwargs): ...
            def critical(self, *args, **kwargs): ...
            def log(self, *args, **kwargs): ...
        return EmptyLogger()
    base_path = GetConfig.root_path
    logLevel = GetConfig.LogLevel
    log_path = base_path / 'log'  # 输入日志目录

    logger = logging.getLogger(name)
    logger.setLevel(logLevel)  # 最底层的日志等级设置，只会记录不低于此等级的日志
    # 自定义日志格式、时间格式，%(msecs)s为毫秒数，%(pathname)s为文件路径
    fmt = "\n>>%(asctime)s.%(msecs).3f %(threadName)s：%(levelname)s %(filename)s %(funcName)s [行号:%(lineno)d] %(message)s\n"
    # datefmt = '%Y-%m-%d %X'
    datefmt = '%X'
    formatter = logging.Formatter(fmt, datefmt)
    logging.addLevelName(25, 'TIP')  # 添加自定义日志等级，介于info与waring之间
    logging.addLevelName(35, 'MARK')  # 添加自定义日志等级，大于error

    print_log = logging.StreamHandler()  # ==>用于输出到控制台的handler1
    print_log.setFormatter(formatter)
    print_log.setLevel(25)

    curTime = time.strftime("%Y-%m-%d_%H∶%M∶%S")
    if time_level == 2:
        curTime = time.strftime("%Y-%m-%d_%H∶%M")
    elif time_level == 3:
        curTime = time.strftime("%Y-%m-%d_%H时")
    elif time_level == 4:
        curTime = time.strftime("%Y-%m-%d")
    elif time_level == 5:
        curTime = time.strftime("%Y-%m")

    log_dir_path = log_path / name
    if not log_dir_path.parent.exists():
        log_dir_path.parent.mkdir(parents=True, exist_ok=True)
    path = log_dir_path / curTime

    run_log = logging.FileHandler(f'{path}_run.log', encoding='utf-8')  # ==>记录所有运行日志的handler2
    run_log.setLevel(logging.INFO)
    run_log.setFormatter(formatter)
    # error_log = logging.FileHandler(f'{path}_error.log', encoding='utf-8')  # ==>仅记录错误日志的handler3
    # error_log.setLevel(logging.ERROR)
    # error_log.setFormatter(formatter)

    logger.addHandler(print_log)  # handler1，等级25
    logger.addHandler(run_log)  # handler2，等级20
    # logger.addHandler(error_log)  # handler3，等级40
    return logger


class ToLog:
    def __init__(self, name, time_level=3, add_stack=0):
        """根据名称写日志，分运行日志和错误日志

        :param name: 日志名，同时也是文件前缀名
        :param time_level: 日志文件时间记录级别，默认3（1秒，2分，3时，4日，5月）
        :param add_stack: 向上增加调用日志所在函数的层级，默认0
        """
        self.tolog = _init_log(name, time_level)
        self.add_stack = add_stack

    def debug(self, msg, add_stack=0, *args, **kwargs):
        """日志等级10"""
        kwargs['stacklevel'] = 2 + self.add_stack + add_stack
        self.tolog.debug(msg, *args, **kwargs)

    def info(self, msg, add_stack=0, *args, **kwargs):
        """日志等级20"""
        kwargs['stacklevel'] = 2 + self.add_stack + add_stack
        self.tolog.info(msg, *args, **kwargs)

    def tip(self, msg, add_stack=0, *args, **kwargs):
        """日志等级25"""
        kwargs['stacklevel'] = 2 + self.add_stack + add_stack
        self.tolog.log(25, msg, *args, **kwargs)

    def warning(self, msg, add_stack=0, *args, **kwargs):
        """日志等级30"""
        kwargs['stacklevel'] = 2 + self.add_stack + add_stack
        self.tolog.warning(msg, *args, **kwargs)

    def mark(self, msg, add_stack=0, *args, **kwargs):
        """日志等级35"""
        kwargs['stacklevel'] = 2 + self.add_stack + add_stack
        self.tolog.log(35, msg, *args, **kwargs)

    def error(self, msg, add_stack=0, *args, **kwargs):
        """日志等级40"""
        kwargs['stacklevel'] = 2 + self.add_stack + add_stack
        self.tolog.error(msg, *args, **kwargs)

    def exception(self, msg, add_stack=0, *args, **kwargs):
        """日志等级40"""
        kwargs['stacklevel'] = 3 + self.add_stack + add_stack
        self.tolog.exception(msg, *args, **kwargs)

    def critical(self, msg, add_stack=0, exc_info=True, stack_info=True, *args, **kwargs):
        """日志等级50"""
        kwargs['stacklevel'] = 2 + self.add_stack + add_stack
        self.tolog.critical(msg, exc_info=exc_info, stack_info=stack_info, *args, **kwargs)

    def log(self, level, msg, add_stack=0, *args, **kwargs):
        """自定义记录等级"""
        kwargs['stacklevel'] = 2 + self.add_stack + add_stack
        self.tolog.log(level, msg, *args, **kwargs)



